{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 字典与集合"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 字典和集合基础\n",
    "\n",
    "- 字典\n",
    "    + 字典访问直接索引键不存在，会报错\n",
    "\n",
    "- 集合\n",
    "    + 集合并不支持索引操作，因为集合本质上是一个哈希表，和列表不一样\n",
    "\n",
    "- 字典 & 集合共性\n",
    "    + 无论键、值，都可以是混合类型\n",
    "    + 判断元素是否在字典或集合内  vaLue in dict/set\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 1, 'b': 2, 'c': 3}\n",
      "{'a': 1, 'b': 2, 'c': 3}\n",
      "{'a': 1, 'b': 2, 'c': 3}\n",
      "{'a': 1, 'b': 2, 'c': 3}\n",
      "{'a': 1, 'b': 2, 'c': 3}\n",
      "None\n",
      "set()\n",
      "{1, 2, 3}\n",
      "{0, 1, 2, 3, 4}\n",
      "{1, 2, 3, 4, 5}\n",
      "{1, 2, 3, 4, 5}\n",
      "{'l', 'o', 'e', 'h'}\n"
     ]
    }
   ],
   "source": [
    "# 字典创建的集中方式\n",
    "d1 = {'a':1, 'b':2, 'c':3}\n",
    "d2 = dict(a=1, b=2, c=3)\n",
    "d3 = dict([('a',1), ('b',2), ('c',3)])\n",
    "d4 = dict(zip(['a','b','c'],[1,2,3]))\n",
    "d5 = dict({'a':1, 'b':2, 'c':3})\n",
    "\n",
    "print(d1)\n",
    "print(d2)\n",
    "print(d3)\n",
    "print(d4)\n",
    "print(d5)\n",
    "# print(d1['d']) # 如果键不存在，会报错 KeyError:d \n",
    "print(d1.get('d')) # 如果键不存在，会返回None\n",
    "# 集合创建的方式\n",
    "s1 = set()\n",
    "s2 = {1,2,3}\n",
    "s3 = set(range(5))\n",
    "s4 = set([1,2,3,4,5])\n",
    "s5 = set((1,2,3,4,5))\n",
    "s6 = set('hello')\n",
    "\n",
    "print(s1)\n",
    "print(s2)\n",
    "print(s3)\n",
    "print(s4)\n",
    "print(s5)\n",
    "print(s6)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d1 = {'a':1, 'b':2, 'c':3}\n",
    "s1 = {1,2,3}\n",
    "\n",
    "'a' in d1\n",
    "2 in s1\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 字典和集合 增 删 改 查"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': 1, 'b': 2, 'c': 3, 'd': 4}\n",
      "{'b': 2, 'c': 3, 'd': 4}\n",
      "{'b': 22, 'c': 3, 'd': 4}\n",
      "22\n",
      "{1, 2, 3, 4}\n",
      "{1, 2, 3}\n",
      "{1, 2, 3, 4, 5}\n",
      "a 1\n",
      "b 2\n",
      "c 3\n",
      "1\n",
      "2\n",
      "3\n",
      "{'a': 1, 'b': 2, 'c': 3}\n",
      "{1, 2, 3}\n"
     ]
    }
   ],
   "source": [
    "# 字典和集合的增删改查\n",
    "# 字典的增删改查\n",
    "# 字典的增\n",
    "d1 = {'a':1, 'b':2, 'c':3}\n",
    "d1['d'] = 4\n",
    "print(d1)\n",
    "\n",
    "# # 字典的删\n",
    "del d1['a']\n",
    "print(d1)\n",
    "\n",
    "# # 字典的改\n",
    "d1['b'] = 22\n",
    "print(d1)\n",
    "\n",
    "# # 字典的查\n",
    "print(d1['b'])\n",
    "\n",
    "# # 集合的增删改查\n",
    "# # 集合的增\n",
    "s1 = {1,2,3}\n",
    "s1.add(4)\n",
    "print(s1)\n",
    "\n",
    "# # 集合的删\n",
    "s1.remove(4)\n",
    "print(s1)   \n",
    "\n",
    "# # 集合的改\n",
    "s1.update({1,2,3,4,5})\n",
    "print(s1)\n",
    "\n",
    "# # 集合的查\n",
    "\n",
    "# # 字典的遍历\n",
    "d1 = {'a':1, 'b':2, 'c':3}\n",
    "for key, value in d1.items():\n",
    "    print(key, value)\n",
    "\n",
    "# # 集合的遍历 \n",
    "s1 = {1,2,3}\n",
    "for item in s1:\n",
    "    print(item)\n",
    "\n",
    "# # 字典的推导式\n",
    "d1 = {'a':1, 'b':2, 'c':3}      \n",
    "d2 = {k:v for k,v in d1.items()}\n",
    "print(d2)\n",
    "\n",
    "# # 集合的推导式\n",
    "s1 = {1,2,3}\n",
    "s2 = {x for x in s1}\n",
    "print(s2)       \n",
    "\n",
    "# # 字典和集合的常用方法\n",
    "# # 字典的常用方法\n",
    "# d1 = {'a':1, 'b':2, 'c':3}\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 字典和集合的排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "按键排序: [('a', 3), ('b', 1), ('c', 2)]\n",
      "按值排序: [('b', 1), ('c', 2), ('a', 3)]\n",
      "集合排序: [1, 3, 5, 9]\n"
     ]
    }
   ],
   "source": [
    "# 字典的排序\n",
    "d1 = {'a':3, 'b':1, 'c':2}\n",
    "\n",
    "sorted_by_key = sorted(d1.items(),key=lambda x: x[0])\n",
    "print(\"按键排序:\", sorted_by_key)\n",
    "\n",
    "sorted_by_value = sorted(d1.items(), key=lambda x: x[1])\n",
    "print(\"按值排序:\", sorted_by_value)\n",
    "\n",
    "# 集合的排序\n",
    "s1 = {1,5,9,3}\n",
    "\n",
    "sorted_set = sorted(s1)\n",
    "print(\"集合排序:\", sorted_set)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 字典和集合性能\n",
    "\n",
    "- 字典\n",
    "    + 和列表相比 O(1) & O(n)\n",
    "    + 字典内部组成是一张哈希表、可以通过键的哈希值找到对应的值\n",
    "\n",
    "- 集合\n",
    "    +  集合是高度优化的哈希表、里面的元素不能重复\n",
    "    +  查找 O(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "time elapse using list: 43.788097899989225\n",
      "time elapse using set: 0.010537600028328598\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "id = [x for x in range(0, 100000)]\n",
    "price = [x for x in range(200000, 300000)]\n",
    "products = list(zip(id, price))\n",
    "\n",
    "\n",
    "def find_unique_price_using_list(products): \n",
    "    unique_price_list = [] \n",
    "    for _, price in products: # A \n",
    "        if price not in unique_price_list: #B \n",
    "            unique_price_list.append(price) \n",
    "    return len(unique_price_list)\n",
    "\n",
    "def find_unique_price_using_set(products): \n",
    "    unique_price_set = set() \n",
    "    for _, price in products: \n",
    "        unique_price_set.add(price) \n",
    "    return len(unique_price_set)\n",
    "    \n",
    "# 计算列表版本的时间\n",
    "start_using_list = time.perf_counter()\n",
    "find_unique_price_using_list(products)\n",
    "end_using_list = time.perf_counter()\n",
    "print(\"time elapse using list: {}\".format(end_using_list - start_using_list))\n",
    "## 输出\n",
    "# time elapse using list: 41.61519479751587\n",
    "\n",
    "# 计算集合版本的时间\n",
    "start_using_set = time.perf_counter()\n",
    "find_unique_price_using_set(products)\n",
    "end_using_set = time.perf_counter()\n",
    "print(\"time elapse using set: {}\".format(end_using_set - start_using_set))\n",
    "# 输出\n",
    "# time elapse using set: 0.008238077163696289"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.5 字典和集合的工作原理\n",
    "\n",
    "\n",
    "- 对于字典而言，这张表存储了哈希值（hash）、键和值这 3 个元素。\n",
    "- 而对集合来说，区别就是哈希表内没有键和值的配对，只有单一的元素了。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
